<template>
  <div class="game-2048">
    <div class="game-layout">
      <!-- 左侧控制区 -->
      <div class="game-controls">
        <div class="game-header">
          <div class="score-board">
            <div class="score">
              <span class="score-label">分数</span>
              <span class="score-value">{{ score }}</span>
            </div>
            <div class="best-score">
              <span class="score-label">最高分</span>
              <span class="score-value">{{ bestScore }}</span>
            </div>
          </div>
          <button @click="newGame" class="new-game-btn">新游戏</button>
        </div>
        
        <div class="game-info">
          <p>使用方向键或点击按钮移动方块，相同数字的方块会合并！</p>
        </div>
        
        <!-- 方向控制按钮 -->
        <div class="direction-controls">
          <button @click="moveUp" class="direction-btn up-btn" :disabled="gameOver">
            <i class="fas fa-chevron-up"></i>
          </button>
          <div class="direction-row">
            <button @click="moveLeft" class="direction-btn left-btn" :disabled="gameOver">
              <i class="fas fa-chevron-left"></i>
            </button>
            <button @click="moveDown" class="direction-btn down-btn" :disabled="gameOver">
              <i class="fas fa-chevron-down"></i>
            </button>
            <button @click="moveRight" class="direction-btn right-btn" :disabled="gameOver">
              <i class="fas fa-chevron-right"></i>
            </button>
          </div>
        </div>
        
        <div class="game-status">
          <div v-if="gameWon" class="status-message won">
            <h4>🎉 恭喜！你赢了！</h4>
            <p>达到了2048！继续游戏挑战更高分数吧！</p>
            <button @click="continueGame" class="continue-btn">继续游戏</button>
          </div>
          
          <div v-if="gameOver" class="status-message game-over">
            <h4>😔 游戏结束</h4>
            <p>无法继续移动了，再试一次吧！</p>
            <button @click="newGame" class="restart-btn">重新开始</button>
          </div>
        </div>
      </div>
      
      <!-- 右侧游戏棋盘 -->
      <div class="game-board">
        <div class="game-container" @keydown="handleKeyDown" @click="focusGame" tabindex="0" ref="gameContainer">
          <div class="grid">
            <div 
              v-for="(row, rowIndex) in grid" 
              :key="rowIndex" 
              class="grid-row"
            >
              <div 
                v-for="(cell, colIndex) in row" 
                :key="colIndex" 
                class="grid-cell"
                :class="getCellClass(cell)"
              >
                <span v-if="cell !== 0" class="cell-number">{{ cell }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Game2048',
  data() {
    return {
      grid: [],
      score: 0,
      bestScore: 0,
      gameWon: false,
      gameOver: false,
      size: 4
    }
  },
  mounted() {
    this.initGame()
    this.loadBestScore()
    this.$nextTick(() => {
      this.focusGame()
    })
  },
  methods: {
    focusGame() {
      if (this.$refs.gameContainer) {
        this.$refs.gameContainer.focus()
      }
    },
    initGame() {
      this.grid = Array(this.size).fill().map(() => Array(this.size).fill(0))
      this.score = 0
      this.gameWon = false
      this.gameOver = false
      this.addRandomTile()
      this.addRandomTile()
    },
    
    loadBestScore() {
      const saved = localStorage.getItem('game2048-best-score')
      this.bestScore = saved ? parseInt(saved) : 0
    },
    
    saveBestScore() {
      if (this.score > this.bestScore) {
        this.bestScore = this.score
        localStorage.setItem('game2048-best-score', this.bestScore.toString())
      }
    },
    
    addRandomTile() {
      const emptyCells = []
      for (let i = 0; i < this.size; i++) {
        for (let j = 0; j < this.size; j++) {
          if (this.grid[i][j] === 0) {
            emptyCells.push({ row: i, col: j })
          }
        }
      }
      
      if (emptyCells.length > 0) {
        const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)]
        this.grid[randomCell.row][randomCell.col] = Math.random() < 0.9 ? 2 : 4
      }
    },
    
    handleKeyDown(event) {
      if (this.gameOver) return
      
      let direction = null
      switch(event.key) {
        case 'ArrowUp':
          direction = 'up'
          break
        case 'ArrowDown':
          direction = 'down'
          break
        case 'ArrowLeft':
          direction = 'left'
          break
        case 'ArrowRight':
          direction = 'right'
          break
        default:
          return
      }
      
      event.preventDefault()
      this.handleMove(direction)
    },
    
    handleMove(direction) {
      if (this.gameOver) return
      
      let moved = false
      const originalGrid = this.grid.map(row => [...row])
      
      switch(direction) {
        case 'up':
          moved = this.moveUpLogic()
          break
        case 'down':
          moved = this.moveDownLogic()
          break
        case 'left':
          moved = this.moveLeftLogic()
          break
        case 'right':
          moved = this.moveRightLogic()
          break
      }
      
      if (moved) {
        this.addRandomTile()
        this.saveBestScore()
        
        if (this.checkWin()) {
          this.gameWon = true
        } else if (this.checkGameOver()) {
          this.gameOver = true
        }
      }
    },
    
    // 按钮点击处理方法
    moveUp() {
      this.handleMove('up')
    },
    
    moveDown() {
      this.handleMove('down')
    },
    
    moveLeft() {
      this.handleMove('left')
    },
    
    moveRight() {
      this.handleMove('right')
    },
    
    // 原有的移动逻辑方法
    moveLeftLogic() {
      let moved = false
      for (let i = 0; i < this.size; i++) {
        const row = this.grid[i].filter(val => val !== 0)
        const merged = this.merge(row)
        
        while (merged.length < this.size) {
          merged.push(0)
        }
        
        for (let j = 0; j < this.size; j++) {
          if (this.grid[i][j] !== merged[j]) {
            moved = true
          }
          this.grid[i][j] = merged[j]
        }
      }
      return moved
    },
    
    moveRightLogic() {
      let moved = false
      for (let i = 0; i < this.size; i++) {
        const row = this.grid[i].filter(val => val !== 0)
        const merged = this.merge(row.reverse()).reverse()
        
        while (merged.length < this.size) {
          merged.unshift(0)
        }
        
        for (let j = 0; j < this.size; j++) {
          if (this.grid[i][j] !== merged[j]) {
            moved = true
          }
          this.grid[i][j] = merged[j]
        }
      }
      return moved
    },
    
    moveUpLogic() {
      let moved = false
      for (let j = 0; j < this.size; j++) {
        const column = []
        for (let i = 0; i < this.size; i++) {
          if (this.grid[i][j] !== 0) {
            column.push(this.grid[i][j])
          }
        }
        
        const merged = this.merge(column)
        
        for (let i = 0; i < this.size; i++) {
          const newValue = i < merged.length ? merged[i] : 0
          if (this.grid[i][j] !== newValue) {
            moved = true
          }
          this.grid[i][j] = newValue
        }
      }
      return moved
    },
    
    moveDownLogic() {
      let moved = false
      for (let j = 0; j < this.size; j++) {
        const column = []
        for (let i = this.size - 1; i >= 0; i--) {
          if (this.grid[i][j] !== 0) {
            column.push(this.grid[i][j])
          }
        }
        
        const merged = this.merge(column)
        
        for (let i = this.size - 1; i >= 0; i--) {
          const newValue = (this.size - 1 - i) < merged.length ? merged[this.size - 1 - i] : 0
          if (this.grid[i][j] !== newValue) {
            moved = true
          }
          this.grid[i][j] = newValue
        }
      }
      return moved
    },
    
    merge(row) {
      const result = []
      let i = 0
      
      while (i < row.length) {
        if (i < row.length - 1 && row[i] === row[i + 1]) {
          const mergedValue = row[i] * 2
          result.push(mergedValue)
          this.score += mergedValue
          i += 2
        } else {
          result.push(row[i])
          i++
        }
      }
      
      return result
    },
    
    checkWin() {
      for (let i = 0; i < this.size; i++) {
        for (let j = 0; j < this.size; j++) {
          if (this.grid[i][j] === 2048) {
            return true
          }
        }
      }
      return false
    },
    
    checkGameOver() {
      // 检查是否还有空格
      for (let i = 0; i < this.size; i++) {
        for (let j = 0; j < this.size; j++) {
          if (this.grid[i][j] === 0) {
            return false
          }
        }
      }
      
      // 检查是否还能合并
      for (let i = 0; i < this.size; i++) {
        for (let j = 0; j < this.size; j++) {
          const current = this.grid[i][j]
          if (
            (i < this.size - 1 && this.grid[i + 1][j] === current) ||
            (j < this.size - 1 && this.grid[i][j + 1] === current)
          ) {
            return false
          }
        }
      }
      
      return true
    },
    
    newGame() {
      this.initGame()
    },
    
    continueGame() {
      this.gameWon = false
    },
    
    getCellClass(value) {
      if (value === 0) return 'cell-empty'
      
      const classes = ['cell-number']
      
      if (value >= 2048) {
        classes.push('cell-2048')
      } else if (value >= 1024) {
        classes.push('cell-1024')
      } else if (value >= 512) {
        classes.push('cell-512')
      } else if (value >= 256) {
        classes.push('cell-256')
      } else if (value >= 128) {
        classes.push('cell-128')
      } else if (value >= 64) {
        classes.push('cell-64')
      } else if (value >= 32) {
        classes.push('cell-32')
      } else if (value >= 16) {
        classes.push('cell-16')
      } else if (value >= 8) {
        classes.push('cell-8')
      } else if (value >= 4) {
        classes.push('cell-4')
      } else {
        classes.push('cell-2')
      }
      
      return classes.join(' ')
    }
  }
}
</script>

<style scoped>
.game-2048 {
  max-width: 100%;
  margin: 0 auto;
  padding: 0;
  background: transparent;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.game-layout {
  display: flex;
  gap: 1.5rem;
  align-items: stretch;
  height: 100%;
}

.game-controls {
  flex: 0 0 380px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 15px;
  padding: 1.5rem;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.game-board {
  flex: 1;
  display: flex;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 15px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

/* 移动端响应式布局 */
@media (max-width: 768px) {
  .game-layout {
    flex-direction: column;
    gap: 1.5rem;
  }
  
  .game-controls {
    flex: none;
    width: 100%;
  }
  
  .game-board {
    width: 100%;
  }
}

.game-header {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}

.game-header h3 {
  background: var(--gradient-rainbow);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  filter: drop-shadow(0 0 10px rgba(92, 225, 255, 0.4));
}

.score-board {
  display: flex;
  gap: 0.8rem;
  width: 100%;
}

.score, .best-score {
  flex: 1;
  background: #bbada0;
  border-radius: 8px;
  text-align: center;
  color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0.8rem 1rem;
}

.score-label {
  display: block;
  font-size: 0.75rem;
  font-weight: 500;
  margin-bottom: 0.2rem;
}

.score-value {
  display: block;
  font-size: 1.3rem;
  font-weight: bold;
}

.new-game-btn {
  background: #8f7a66;
  color: white;
  border: none;
  padding: 0.6rem 1.2rem;
  border-radius: 5px;
  font-size: 0.95rem;
  font-weight: bold;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.new-game-btn:hover {
  background: #9f8a76;
}

.game-info {
  text-align: center;
  color: #e0e0e0;
  font-size: 0.85rem;
  font-weight: 500;
}

.game-info p {
  margin: 0;
}

/* 方向控制按钮 */
.direction-controls {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
}

.direction-row {
  display: flex;
  gap: 0.4rem;
}

.direction-btn {
  width: 45px;
  height: 45px;
  border: 2px solid #bbada0;
  border-radius: 8px;
  background: #faf8ef;
  color: #776e65;
  font-size: 1.1rem;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.direction-btn:hover:not(:disabled) {
  background: #eee4da;
  border-color: #9f8a77;
  transform: scale(1.05);
}

.direction-btn:active:not(:disabled) {
  transform: scale(0.95);
}

.direction-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.up-btn {
  margin-bottom: 0.25rem;
}

.game-container {
  background: #bbada0;
  border-radius: 10px;
  padding: 10px;
  outline: none;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.grid {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 10px;
  width: 370px;
  height: 370px;
}

.grid-row {
  display: flex;
  gap: 10px;
}

.grid-cell {
  width: 80px;
  height: 80px;
  background: #cdc1b4;
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  font-weight: bold;
  transition: all 0.15s ease;
}

.cell-empty {
  background: #cdc1b4;
}

.cell-number {
  color: #776e65;
}

/* 数字颜色样式 - 经典2048风格 */
.cell-2 { background: #eee4da; color: #776e65; }
.cell-4 { background: #ede0c8; color: #776e65; }
.cell-8 { background: #f2b179; color: #f9f6f2; }
.cell-16 { background: #f59563; color: #f9f6f2; }
.cell-32 { background: #f67c5f; color: #f9f6f2; }
.cell-64 { background: #f65e3b; color: #f9f6f2; }
.cell-128 { background: #edcf72; color: #f9f6f2; font-size: 1.2rem; }
.cell-256 { background: #edcc61; color: #f9f6f2; font-size: 1.2rem; }
.cell-512 { background: #edc850; color: #f9f6f2; font-size: 1.2rem; }
.cell-1024 { background: #edc53f; color: #f9f6f2; font-size: 1rem; }
.cell-2048 { background: #edc22e; color: #f9f6f2; font-size: 1rem; }

.game-status {
  text-align: center;
}

.status-message {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(15px);
  -webkit-backdrop-filter: blur(15px);
  border-radius: 15px;
  padding: 2rem;
  margin-bottom: 1rem;
  border: 1px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}

.status-message h4 {
  margin: 0 0 1rem 0;
  font-size: 1.3rem;
  color: #ffffff;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}

.status-message p {
  margin: 0 0 1rem 0;
  color: #e0e0e0;
}

.won h4 {
  color: #97dc99;
  text-shadow: 0 2px 4px rgba(151, 220, 153, 0.5);
}

.game-over h4 {
  color: #97dc99;
  text-shadow: 0 2px 4px rgba(151, 220, 153, 0.5);
}

.continue-btn, .restart-btn {
  background: linear-gradient(135deg, #97dc99 0%, #88c057 100%);
  color: #ffffff;
  border: none;
  padding: 0.8rem 1.5rem;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(151, 220, 153, 0.3);
}

.continue-btn:hover, .restart-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(151, 220, 153, 0.5);
}

@media (max-width: 600px) {
  .game-header {
    flex-direction: column;
    align-items: center;
  }
  
  .score-board {
    justify-content: center;
  }
  
  .direction-controls {
    display: none; /* 在移动设备上隐藏方向按钮，使用触摸滑动 */
  }
  
  .grid {
    width: 270px;
    height: 270px;
  }
  
  .grid-cell {
    width: 60px;
    height: 60px;
    font-size: 1.2rem;
  }
  
  .cell-128, .cell-256, .cell-512 {
    font-size: 1rem;
  }
  
  .cell-1024, .cell-2048 {
    font-size: 0.8rem;
  }
}

@media (max-width: 480px) {
  .grid {
    width: 230px;
    height: 230px;
  }
  
  .grid-cell {
    width: 50px;
    height: 50px;
    font-size: 1rem;
  }
  
  .cell-128, .cell-256, .cell-512 {
    font-size: 0.9rem;
  }
  
  .cell-1024, .cell-2048 {
    font-size: 0.7rem;
  }
}
</style>
